﻿//using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;
using Nemerle.Data;
using Nemerle.Data.NList;

using System;
using System.Collections.Generic;
using System.Console;
using System.Linq;

using CCombinator.BenchmarkToolKit;

module Program
{
  MakeNListList[T](lst : list[T]) : list[T]
  {
     def r = List(); 
     foreach(x in lst) r.Add(x); 
     r.ToArray().ToNList()
  }
  
  MakeNListListBuilder[T](lst : list[T]) : list[T]
  {
     def r = ListBuilder(); 
     foreach(x in lst) r.Add(x); 
     r.ToNList()
  }
  
  Main() : void
  {
    //Benchmark.WarmUp();
    //        Benchmark.ComparativeReport("Parsers benchmark",
    //                                    Tuple.Create("my", Benchmark.Run(CCombinator.PC.Test.Create(td.Item1), 3).Ensure(td.Item2).Seconds()),
    //                                    Tuple.Create("rsdn", Benchmark.Run(RSDNPCTest.Test.Create(td.Item1), 3).Ensure(td.Item2).Seconds())
    //            );
    Benchmark.WarmUp();
    
    foreach(k in [1, 10, 100, 1000, 10000, 100000, 1000000])
    {
    
    def max = 10000000;
    //def lst = $[0 .. max];
    //def k = 10000;
    def lst2 = $[0 .. max/k];
    
    //def arr = Arrays.Replicate(7, max);
    
    def arr2 = lst2.ToArray();
    
    
    Benchmark.ComparativeReport($"benchmark $(max/k)",
      KeyValuePair("array", Benchmark.Run(() => repeat(k){ _ = arr2.Map(_ * 2).Filter(x => x % 2 == 0).FoldLeft(0.0,  _ + _); }, 10).Seconds()),
      KeyValuePair("[]", Benchmark.Run(() => repeat(k){ _ = NLists.FoldLeft(NLists.Filter(NLists.Map(lst2, _ * 2), x => x % 2 == 0), 0.0, _ + _); }, 10).Seconds()),
      KeyValuePair("[] w.o. rev", Benchmark.Run(() => repeat(k){ _ = NLists.FoldLeft(NLists.FilterRev(NLists.MapRev(lst2, _ * 2), x => x % 2 == 0), 0.0, _ + _); }, 10).Seconds()),
      KeyValuePair("seq(array)", Benchmark.Run(() => repeat(k){ _ = arr2.MapSeq(_ * 2).FilterSeq(x => x % 2 == 0).FoldLeftSeq(0.0, _ + _); }, 10).Seconds()),
      KeyValuePair("seq(list)", Benchmark.Run(() => repeat(k){ _ = lst2.MapSeq(_ * 2).FilterSeq(x => x % 2 == 0).FoldLeftSeq(0.0, _ + _); }, 10).Seconds())
    );
  }
    
    //Benchmark.ComparativeReport("ScanLeft benchmark 2.",
    //  KeyValuePair("List", Benchmark.Run(() => repeat(k){ _ = MakeNListList(lst2) }, 10).Seconds()),
    //  KeyValuePair("ListBuilder", Benchmark.Run(() => repeat(k){ _ = MakeNListListBuilder(lst2) }, 10).Seconds())
    //);   
    
    //Benchmark.ComparativeReport("ScanLeft benchmark 2.",
    //  KeyValuePair("List", Benchmark.Run(() => repeat(k){ _ = lst2.ScanLeft(0.0, _*_); }, 10).Seconds()),
    //  KeyValuePair("[]", Benchmark.Run(() => repeat(k){ _ = lst2.ScanLeft'(0.0, _*_); }, 10).Seconds())
    //);   
    //Benchmark.ComparativeReport("ScanLeft benchmark.",
    //  KeyValuePair("List", Benchmark.Run(() => { _ = lst.ScanLeft(0.0, _*_); }, 10).Seconds()),
    //  KeyValuePair("[]", Benchmark.Run(() => { _ = lst.ScanLeft'(0.0, _*_); }, 10).Seconds())
    //);
    
    //Benchmark.ComparativeReport("ToNList benchmark.",
    //  KeyValuePair("foreach", Benchmark.Run(() => { _ = arr.ToNList(); }, 10).Seconds()),
    //  KeyValuePair("$[]", Benchmark.Run(() => { _ = arr.ToNList'(); }, 10).Seconds()),
    //  KeyValuePair("for", Benchmark.Run(() => { _ = arr.ToNList'''(); }, 10).Seconds()),
    //  KeyValuePair("rec", Benchmark.Run(() => { _ = arr.ToNList''(); }, 10).Seconds())
    //);
    
    
    //Benchmark.ComparativeReport("TakeAtMost benchmark.",
    //KeyValuePair("[]", Benchmark.Run(() => { _ = NLists.TakeAtMost(lst, max/2); }, 10).Seconds()),
    //  KeyValuePair("foreach", Benchmark.Run(() => { _ = NLists.TakeAtMost'(lst, max/2); }, 10).Seconds()),
    //  KeyValuePair("Stack", Benchmark.Run(() => { _ = NLists.TakeAtMost'(lst, max/2); }, 10).Seconds()));
    
    
    _ = ReadLine();
  }
}